#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

#define N 1
#define TASK_NUM 10
typedef void (*task_t)();
void task1() { printf("这是一个打印界面的程序\n"); }
void task2() { printf("这是一个检查网络状态的脚本\n");}
void task3() { printf("我正在写日志\n"); }
task_t tasks[TASK_NUM];

void initTask()
{
  for(int i = 0; i < TASK_NUM; ++i)
    tasks[i] = NULL;
}

int addTask(task_t t)
{
  int pos = 0;
  for(; pos < TASK_NUM; ++pos)
      if(tasks[pos] == NULL)
      {
        tasks[pos] = t;
        return 1;
      }
  return -1;
}

void runTask()
{
  for(int i = 0; i < TASK_NUM; ++i)
      if(tasks[i])
        tasks[i]();
}

void runchild()
{
  int cnt = 10;
  while(cnt)
  {
    printf("I'm child, my pid is : %d, my ppid is : %d\n", getpid(), getppid());
    --cnt;
    sleep(1);
  }
}

int main()
{
  for(int i = 0; i < N; ++i)
  {
    pid_t id = fork();
    //如果返回值大于0，说明是子进程
    if(id ==  0)
    {
      runchild();
      exit(0);
    }
  }
  //sleep(5);
  //sleep之后，5个子进程都变成了僵尸进程，需要父进程等待之后才能死亡
  //阻塞等待,如果子进程一直不退出，那么父进程也不会退出
 // for(int i = 0; i < N; ++i)
 // {
 //   int status = 0;
 //   //wait(int* status),会将信号和退出码保存到status中
 //   pid_t id = wait(&status);
 //   //if(id > 0)
 //   //printf("wait success, child pid is : %d, singal is: %d, exit code: %d\n", id, status&0x7f, (status>>8)&0xff);
 //   //WIFEXIED宏的用处是检查是否正常退出，正常退出返回真
 //   if(WIFEXITED(status))
 //   {
 //     //WEXITSTATUS宏表示提取进程退出码
 //     printf("exit code:%d\n", WEXITSTATUS(status));
 //   }
 //   else{
 //     printf("程序异常退出\n");
 //   }
 // }
 // sleep(5);
 // ///////////////////////////////////////////////
  //非阻塞轮询
  //父进程一直询问，只有当子进程任务完成的时候，等待才成功
  int num = 0;
  addTask(task1);
  addTask(task2);
  addTask(task3);
  while(num < N)
  {
    int status = 0;
    pid_t id = waitpid(-1, &status, WNOHANG);
    if(id == 0)
    {
      printf("子进程还没有结束，我再等等！\n");
      runTask();
      usleep(500000);
    }
    else if(id > 0)
    {
      printf("wait success, child pid: %d, singal : %d, exit code: %d\n", id, status&0x7f, (status>>8)&0xff);
      ++num;
    }
    sleep(1);
  }
  return 0;
}
